package com.yuji.aacar.core.mvvm.apptask;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.TextUtils;

import com.yuji.aacar.core.cores.event.CoreEventCenter;
import com.yuji.aacar.core.cores.excep.ExceptionController;
import com.yuji.aacar.core.cores.services.CoreServiceMediator;
import com.yuji.aacar.core.cores.services.CoreServiceResponse;
import com.yuji.aacar.core.cores.utils.LogUtil;
import com.yuji.aacar.core.mvvm.appbase.AppRoute;
import com.yuji.aacar.core.mvvm.appbase.CoreBaseFragment;
import com.yuji.aacar.core.mvvm.appbase.CoreBaseViewModel;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * <li>Package:com.ttp.core.mvvm.appbase</li>
 * <li>Author: lining</li>
 * <li>Date: 2017/2/14</li>
 * <li>Description:<br> 统一管理 viewmodel的创建，与activity关联,以及doTask请求返回的handel处理</br></li>
 */

public class ViewModelManager {

	private static ViewModelManager vmManager;

	//生成的activity@1 id对象，缓存跳转的actiivy关系的id
//	private static HashMap<String, CoreBaseViewModel> viewModelMap;
	private static ConcurrentMap<String, CoreBaseViewModel> viewModelMap;
	//绑定关系列表总表
	private static HashMap<String, String> viewModelPlist;
	//绑定异常
	private ExceptionController controller;

	public static ViewModelManager getInstance() {
		synchronized (AppRoute.class) {
			if (vmManager == null) {
				vmManager = new ViewModelManager();
			}
			return vmManager;
		}
	}

	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			handlerMessage(msg);
		}
	};

	public Handler getHandler() {
		return handler;
	}

	private ViewModelManager() {
		viewModelMap = new ConcurrentHashMap<String, CoreBaseViewModel>();
	}

	/**
	 * 通过msg 通知各个activity对应的model对象
	 * @param msg
     */
	private void handlerMessage(Message msg) {
		CoreServiceResponse response = (CoreServiceResponse) msg.obj;
		TaskToken token = (TaskToken) response.getTokenObj();
		if (null != token){
			LogUtil.e("--handlerMessage-----token--", token);
			String viewModelId = token.viewModelId;
			CoreBaseViewModel model = viewModelForKey(viewModelId);
			LogUtil.e("--handlerMessage-----token--", token);
			LogUtil.e("--handlerMessage-------viewModelId--", viewModelId);
			LogUtil.e("--handlerMessage-----model--", model);
			if (null != model) {
				switch (msg.what) {
					case CoreServiceMediator.Service_Return_Success:
						model.setResponse(response);
						break;
					default:
						model.requestFailed(response);
						break;
				}
			}
		}else{
			CoreEventCenter.postMessage(CoreEventCenter.NETWOR_NOT_CONNECT ,"网络失败");
		}

	}

	/**
	 * 直接通知各个activity对应的model对象
	 * @param response
	 */
	public void notifyViewModel(CoreServiceResponse response) {

//		String requestCode = String.valueOf(response.getHeader().getService());
//		response.getHeader();
		TaskToken token = (TaskToken) response.getTokenObj();
		if (null != token){
			String viewModelId = token.viewModelId;
			CoreBaseViewModel model = viewModelForKey(viewModelId);
			LogUtil.e("--ViewModelManager---notifyViewModel--token--", token);
			LogUtil.e("--ViewModelManager---notifyViewModel----viewModelId--", viewModelId);
			LogUtil.e("--ViewModelManager---notifyViewModel--model--", model==null?"这个model对象被销毁了":model);
			LogUtil.e("--ViewModelManager---notifyViewModel--response--", response);
			if (null != model) {
				switch (response.getResultCode()) {
					case CoreServiceMediator.Service_Return_Success:
						model.exception = null;
						model.setResponse(response);
						break;
					default:
						//TODO 还有验证码等业务异常还需要在后面处理
//						model.exception = controller.throwException(String.valueOf(response.getResultCode()),response.getMessage());
						//					response.setResultCode(model.exception.getCode());
						//					response.setReturnDesc(model.exception.getErrorMessage());
//						LogUtil.e("--exception-----errorCode--", model.exception.getCode());
//						LogUtil.e("--exception-----errorMessage--", model.exception.getErrorMessage());
						model.requestFailed(response);
						break;
				}
			}
		}else {
			LogUtil.e("--ViewModelManager---notifyViewModel--token--为空， 请检查服务端是否返回了serviceCode", "");
		}
	}

	/**
	 * 传入viewmodelplist中实现的，activity和viewmodel对应关系的hashmp
	 */
	public void addViewModelPlist(HashMap<String, String> map) {
		if (viewModelPlist == null) {
			viewModelPlist = map;
		} else {
			viewModelPlist.putAll(map);
		}
	}

	/**
	 * 根据activity类名，从view model plist 中获取对应的viewmodel类名，并实例化，生成viewModelId,activity集合
	 * 
	 * @param classString
	 *            需要的viewmodel的activity类名
	 * @return 实例化的view model对象
	 */
	public synchronized CoreBaseViewModel newViewModel(String classString) {
		String viewModelId = classString + "@"
				+ TaskManager.getInstance().getActivityCounter();
		LogUtil.e("--newViewModel--", viewModelId);
		LogUtil.e("--newViewModel--viewModelMap缓存中有几个view？ ", viewModelMap.isEmpty()?"0":viewModelMap.size());
		CoreBaseViewModel resultViewModel = viewModelMap.get(viewModelId);
		LogUtil.e("--newViewModel--缓存中是否有这个id对应的view？   ", resultViewModel==null?"没有":"有");
		if (null == resultViewModel) {
			String strClass = viewModelPlist.get(classString);
			try {
				resultViewModel = (CoreBaseViewModel) Class.forName(strClass)
						.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			resultViewModel.setViewModelId(viewModelId);
			resultViewModel.setActivityClass(classString);
			viewModelMap.put(viewModelId, resultViewModel);
			LogUtil.e("--newViewModel--新生成一个viewmodel对象   ", resultViewModel);
		}
		return resultViewModel;
	}

	public synchronized CoreBaseViewModel newViewModelWithActivity (Activity activity) {
		String classString = activity.getClass().getName();
		String viewModelId = classString + "@"
				+ TaskManager.getInstance().getActivityCounter();

		CoreBaseViewModel resultViewModel = viewModelMap.get(viewModelId);
		if (null == resultViewModel) {
			String strClass = viewModelPlist.get(classString);
			try {
				resultViewModel = (CoreBaseViewModel) Class.forName(strClass)
						.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			resultViewModel.setViewModelId(viewModelId);
			resultViewModel.setActivityClass(classString);
			resultViewModel.setActivity(activity);
			viewModelMap.put(viewModelId, resultViewModel);
		}
		return resultViewModel;
	}

	public synchronized CoreBaseViewModel newViewModelWithFragment (Fragment fragment) {
		String classString = fragment.getClass().getName();
		String viewModelId = classString + "@"
				+ TaskManager.getInstance().getActivityCounter();

		CoreBaseViewModel resultViewModel = viewModelMap.get(viewModelId);
		if (null == resultViewModel) {
			String strClass = viewModelPlist.get(classString);
			try {
				resultViewModel = (CoreBaseViewModel) Class.forName(strClass)
						.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			resultViewModel.setViewModelId(viewModelId);
			resultViewModel.setActivityClass(classString);
			resultViewModel.setActivity(fragment.getActivity());
			resultViewModel.setFragment(fragment);
			viewModelMap.put(viewModelId, resultViewModel);
		}
		((CoreBaseFragment)resultViewModel.getFragment()).setViewModel(resultViewModel);
		return resultViewModel;
	}


	/**
	 * 根据viewModelId 获取manager中已存在对应的viewModel
	 * 
	 * @param viewModelId
	 *            一个activity的唯一标示符
	 * 
	 * @return 实例化的view model对象
	 */
	public CoreBaseViewModel viewModelForKey(String viewModelId) {
		LogUtil.e("---viewModelForKey---",viewModelMap.size());
		LogUtil.e("---viewModelForKey---",viewModelMap);
		CoreBaseViewModel resultViewModel = null;
		if (null != viewModelId){
			if (viewModelMap.containsKey(viewModelId)){
				resultViewModel = viewModelMap.get(viewModelId);
			}
		}
		return resultViewModel;
	}

	/**
	 * 销毁viewmodel
	 */
	public void destoryViewModel(String viewModelId) {
		if(TextUtils.isEmpty(viewModelId)){
			return;
		}
		LogUtil.e("---destoryViewModel---viewModelId--", viewModelId);
		LogUtil.e("---destoryViewModel---viewModelMap left --", viewModelMap.size());
		viewModelMap.remove(viewModelId);
		Set<String> keys = viewModelMap.keySet();
		if(!viewModelId.contains("@")){
			return;
		}
		String startStr = viewModelId.substring(0, viewModelId.indexOf("@") + 1);
		for (Iterator it = keys.iterator(); it.hasNext();) {
			String key = (String) it.next();
			if (key.startsWith(startStr)) {
				viewModelMap.remove(viewModelId);
			}
		}
		LogUtil.e("---destoryViewModel---销毁后剩余--", viewModelMap.size());
	}

	/**
	 * 新增viewmodel
	 *
	 * 做页面请求时不能使用此接口
	 * 为了脱离activity单独做网络请求添加此接口
	 * 	要求：使用者在网络请求后要手动删除viewmodel
	 * 		 使用destoryViewModel(String viewModelId)删除viewmodel
	 *
	 * 	return false 添加viewmodel失败
	 * 	return true  添加viewmodel成功
	 */
	public boolean addNewViewModel(CoreBaseViewModel viewModel){
		String viewModelId = viewModel.getClass().getName()+"@";
		viewModel.setViewModelId(viewModelId);
		if(viewModelMap.containsKey(viewModelId)){
			return false;
		}else{
			viewModelMap.put(viewModelId,viewModel);
			return true;
		}
	}

	/**
	 * 返回当前各容器信息
	 * @return
     */
	public String getVMInfo(){
		StringBuilder str = new StringBuilder();
		str.append("viewModelMap size:");
		str.append(viewModelMap == null ? "null" : viewModelMap.size());
		str.append(" | ");
		str.append("viewModelPlist size:");
		str.append(viewModelPlist == null ? "null" : viewModelPlist.size());

		return str.toString();
	}

	public void setController(ExceptionController controller) {
		this.controller = controller;
	}
}
